package com.tools.cleanmaster.ui.view.trash;

import android.content.Context;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.tools.cleanmaster.CleanApplication;
import com.tools.cleanmaster.CleanConstant;
import com.tools.cleanmaster.R;
import com.tools.cleanmaster.common.imagecache.ImageCache;
import com.tools.cleanmaster.common.imagecache.ImageRequestApkFile;
import com.tools.cleanmaster.model.item.TrashItem;
import com.tools.cleanmaster.ui.view.CheckBoxThreeStates;
import com.tools.cleanmaster.utils.FeatureConfig;
import com.tools.cleanmaster.utils.LogHelper;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("static-access")
public class TrashCleanListAdapter extends BaseExpandableListAdapter implements OnGroupClickListener {

    private static final int CHILD_TYPE_ITEM = 0;
    private static final int CHILD_TYPE_LIST = 1;
    private final ExpandableListView mListView;
    protected int mGroupItemLayoutRes = R.layout.trash_clean_base_item;
    protected int mChildItemLayoutRes = R.layout.trash_clean_second_level_item;
    private final TrashCleanListAdapter mParentAdapter;
    protected final LayoutInflater mInflater;
    protected List<TrashCleanListAdapter> mChildListAdapters = new ArrayList<TrashCleanListAdapter>();
    protected final TrashScanListener mTrashScanListener;
    protected final OnChildClickListener mChildClickListener;
    protected final Context mContext;
    protected List<TrashGroup> mTrashGroups;

    public interface TrashScanListener {

        void onTrashSizeChanged();
    }

    public class ItemOnCheckedChangeListener implements OnCheckedChangeListener {
        TrashViewItem mItem;

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (mItem != null) {
                if (mItem.isChecked() != isChecked) {
                    mItem.onCheckedChanged(isChecked, true);
                    notifyAllDataSetChanged();
                    mTrashScanListener.onTrashSizeChanged();
                }
            }

        }

    }

    public TrashCleanListAdapter(Context context, List<TrashGroup> trashGroups, TrashScanListener listener,
                                 OnChildClickListener childClickListener, ExpandableListView listView) {
        this(context, trashGroups, listener, null, childClickListener, listView);
    }

    public TrashCleanListAdapter(Context context, List<TrashGroup> trashGroups, TrashScanListener listener,
                                 TrashCleanListAdapter parent, OnChildClickListener childClickListener, ExpandableListView listView) {
        if (context == null || trashGroups == null || listener == null) {
            throw new IllegalArgumentException("Null args is not acceptable");
        }
        mContext = context;
        mTrashGroups = trashGroups;
        mTrashScanListener = listener;
        mParentAdapter = parent;
        mChildClickListener = childClickListener;
        mInflater = LayoutInflater.from(context);
        mListView = listView;
    }

    public List<TrashGroup> getTrashGroups() {
        return mTrashGroups;
    }

    @Override
    public int getGroupCount() {
        return mTrashGroups.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        List<TrashViewItem> childItems = mTrashGroups.get(groupPosition).getChildItems();
        if (childItems != null) {
            return childItems.size();
        } else {
            return 0;
        }
    }

    @Override
    public Object getGroup(int groupPosition) {
        return mTrashGroups.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return null;
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return 0;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        ItemViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(mGroupItemLayoutRes, null);
            holder = onCreateGroupViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ItemViewHolder) convertView.getTag();
        }
        TrashGroup group = mTrashGroups.get(groupPosition);
        holder.mCheckChangedListener.mItem = group;
        holder.mIcon.setImageDrawable(group.getIcon());
        holder.mTitle.setText(group.getTitle());
        holder.mSize.setVisibility(View.VISIBLE);
        holder.mCheck.setVisibility(View.VISIBLE);
        holder.mSize.setText(group.getStatus());
        holder.mCheck.setChecked(group.isChecked(), group.isHalfChecked());
        holder.mDividerHead.setVisibility(View.VISIBLE);
        holder.mDividerEnd.setVisibility(View.GONE);
        if (mListView.isGroupExpanded(groupPosition)) {
            holder.mDividerEnd.setVisibility(View.VISIBLE);
        } else {
            holder.mDividerEnd.setVisibility(View.GONE);
        }
        boolean isLast = groupPosition == mTrashGroups.size() - 1;
        if (isLast) {
            holder.mDividerEnd.setVisibility(View.VISIBLE);
        }
        if (holder.mIndicator != null) {
            holder.mIndicator.setImageDrawable(mContext.getResources().getDrawable(
                    isExpanded ? R.drawable.list_indicator_up : R.drawable.list_indicator_down));
        }

        return convertView;
    }

    ItemViewHolder onCreateGroupViewHolder(View convertView) {
        ItemViewHolder holder = new ItemViewHolder();
        ImageView icon = convertView.findViewById(R.id.icon);
        TextView tv = convertView.findViewById(R.id.title);
        TextView size = convertView.findViewById(R.id.size);
        CheckBoxThreeStates checkbox = convertView.findViewById(R.id.check);
        holder.mIcon = icon;
        holder.mTitle = tv;
        holder.mSize = size;
        holder.mCheck = checkbox;
        holder.mCheckChangedListener = new ItemOnCheckedChangeListener();
        checkbox.setOnCheckedChangeListener(holder.mCheckChangedListener);
        holder.mDividerHead = convertView.findViewById(R.id.second_level_divider);
        holder.mDividerEnd = convertView.findViewById(R.id.second_level_divider_end);
        holder.mIndicator = convertView.findViewById(R.id.indicator);
        return holder;
    }

    protected View onPrepareChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                                      ViewGroup parent) {
        TrashGroup group = mTrashGroups.get(groupPosition);
        ItemViewHolder holder;
        TrashViewItem trash = group.getChildItems().get(childPosition);
        boolean needCreateView = convertView == null;
        if (convertView != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
            Integer type = (Integer) convertView.getTag(R.id.trash_clean_view_type);
            needCreateView = type == null || type != CHILD_TYPE_ITEM;
        }
        if (needCreateView) {
            convertView = mInflater.inflate(mChildItemLayoutRes, null);
            ImageView icon = convertView.findViewById(R.id.icon);
            TextView title = convertView.findViewById(R.id.title);
            TextView size = convertView.findViewById(R.id.size);
            CheckBoxThreeStates check = convertView.findViewById(R.id.check);
            LinearLayout summary = convertView.findViewById(R.id.summary);
            TextView fstSum = convertView.findViewById(R.id.summary_fst);
            TextView sndSum = convertView.findViewById(R.id.summary_snd);
            holder = new ItemViewHolder();
            holder.mIcon = icon;
            holder.mTitle = title;
            holder.mSize = size;
            holder.mCheck = check;
            holder.mCheckChangedListener = new ItemOnCheckedChangeListener();
            holder.mSummary = summary;
            holder.mFstSummary = fstSum;
            holder.mSndSummary = sndSum;
            check.setOnCheckedChangeListener(holder.mCheckChangedListener);
            holder.mDividerHead = convertView.findViewById(R.id.second_level_divider);
            holder.mDividerEnd = convertView.findViewById(R.id.second_level_divider_end);
            convertView.setTag(holder);
            convertView.setTag(R.id.trash_clean_view_type, CHILD_TYPE_ITEM);
        } else {
            holder = (ItemViewHolder) convertView.getTag();
        }
        if (trash instanceof TrashApkGroup.ApkTrash) {
            ImageCache.getInstance().loadImage(holder.mIcon,
                    CleanApplication.getInstance().getResources().getDrawable(R.drawable.transhcleaning_apktrash),
                    new ImageRequestApkFile(((TrashApkGroup.ApkTrash) trash).mApkItem.filePath));
            TrashApkGroup.ApkTrash apkTrash = (TrashApkGroup.ApkTrash) trash;
            holder.mSummary.setVisibility(View.VISIBLE);
            holder.mFstSummary.setText(mContext.getString(R.string.trash_clean_apk_version, apkTrash.getVersion()));
            holder.mSndSummary.setText(apkTrash.getInstalledDesc());
        } else {
            holder.mIcon.setTag(ImageCache.TAG_IMAGE_IS_LOADING, false);
            holder.mIcon.setImageDrawable(trash.getIcon());
            if (holder.mSummary != null) {
                holder.mSummary.setVisibility(View.GONE);
            }
        }
        if (group instanceof TrashSysCacheGroup) {
            holder.mCheck.setVisibility(View.INVISIBLE);
        } else {
            holder.mCheck.setVisibility(View.VISIBLE);
        }
        holder.mTitle.setText(trash.getTitle());
        holder.mSize.setText(trash.getStatus());
        holder.mCheckChangedListener.mItem = trash;
        holder.mCheck.setChecked(trash.isChecked(), trash.isHalfChecked());
        if (holder.mDividerHead != null) {
            holder.mDividerHead.setVisibility(View.GONE);
        }
        if (holder.mDividerEnd != null) {
            holder.mDividerEnd.setVisibility(View.VISIBLE);
        }
        if (childPosition == (group.getChildItems().size() - 1)) {
            holder.mDividerHead.setVisibility(View.GONE);
            holder.mDividerEnd.setVisibility(View.GONE);
        }
        return convertView;
    }

    protected View onPrepareChildGroupView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                                           ViewGroup parent) {
        TrashGroup group = (TrashGroup) mTrashGroups.get(groupPosition).getChildItems().get(childPosition);
        List<TrashGroup> childGroup = new ArrayList<TrashGroup>(1);
        childGroup.add(group);
        boolean needCreateView = convertView == null;
        boolean isFirst = childPosition == 0;
        if (convertView != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
            Integer type = (Integer) convertView.getTag(R.id.trash_clean_view_type);
            needCreateView = type == null || type != CHILD_TYPE_LIST;
        }
        TrashCleanChildExpandableListView listView;
        if (needCreateView) {
            listView = new TrashCleanChildExpandableListView(mContext);
            listView.setOnChildClickListener(mChildClickListener);
            listView.setOnGroupClickListener(this);
            TrashCleanListAdapter adpater = createChildExpandableListAdapter(childGroup, listView);
            ((TrashCleanChildExpandableListView.TrashCleanChildExpandableListAdapter) adpater).setFirstInParent(isFirst);
            mChildListAdapters.add(adpater);
            listView.setAdapter(adpater);
            convertView = listView;
            convertView.setTag(R.id.trash_clean_view_type, CHILD_TYPE_LIST);
        } else {
            listView = (TrashCleanChildExpandableListView) convertView;
            TrashCleanListAdapter adapter = (TrashCleanListAdapter) listView.getExpandableListAdapter();
            ((TrashCleanChildExpandableListView.TrashCleanChildExpandableListAdapter) adapter).setFirstInParent(isFirst);
            adapter.mTrashGroups = childGroup;
            adapter.notifyDataSetChangedOnly();
        }
        if (group instanceof TrashGroupWithIndicator) {
            if (((TrashGroupWithIndicator) group).mIsExpand) {
                if (!listView.isGroupExpanded(0)) {
                    listView.expandGroup(0);
                }
            } else {
                if (listView.isGroupExpanded(0)) {
                    listView.collapseGroup(0);
                }
            }
        }
        return convertView;
    }

    protected TrashCleanChildExpandableListView.TrashCleanChildExpandableListAdapter createChildExpandableListAdapter(List<TrashGroup> childGroup,
                                                                                                                      TrashCleanChildExpandableListView listView) {
        return new TrashCleanChildExpandableListView.TrashCleanChildExpandableListAdapter(mContext, childGroup, mTrashScanListener, this, listView);
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                             ViewGroup parent) {
        TrashViewItem childItem = mTrashGroups.get(groupPosition).getChildItems().get(childPosition);
        if (childItem instanceof TrashGroup) {
            return onPrepareChildGroupView(groupPosition, childPosition, isLastChild, convertView, parent);
        } else {
            return onPrepareChildView(groupPosition, childPosition, isLastChild, convertView, parent);
        }
    }

    @Override
    public int getChildType(int groupPosition, int childPosition) {
        TrashGroup group = mTrashGroups.get(groupPosition);
        if (group != null) {
            List<TrashViewItem> childItems = group.getChildItems();
            if (childItems == null || childItems.isEmpty() || childItems.get(0) instanceof TrashViewItemSingle) {
                return CHILD_TYPE_ITEM;
            } else {
                return CHILD_TYPE_LIST;
            }
        }
        if (FeatureConfig.DEBUG_LOG) {
            LogHelper.w(CleanConstant.TAG,
                    "getChildType from invalid groupPosition" + groupPosition + " and childPosition:" + childPosition);
        }
        return super.getChildType(groupPosition, childPosition);
    }

    @Override
    public int getChildTypeCount() {
        return 2;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    @Override
    public void notifyDataSetChanged() {
        notifyAllDataSetChanged();
    }

    final void notifyAllDataSetChanged() {
        if (mParentAdapter != null) {
            mParentAdapter.notifyDataSetChangedOnly();
        } else {
            super.notifyDataSetChanged();
            for (TrashCleanListAdapter adapter : mChildListAdapters) {
                adapter.notifyDataSetChangedOnly();
            }
        }
    }

    final void notifyDataSetChangedOnly() {
        super.notifyDataSetChanged();
    }

    @Override
    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
        if (parent instanceof ExpandableListView) {
            ItemViewHolder holder = (ItemViewHolder) v.getTag();
            TrashCleanListAdapter adapter = (TrashCleanListAdapter) parent.getExpandableListAdapter();
            TrashGroup group = adapter.getTrashGroups().get(groupPosition);
            boolean expanded = parent.isGroupExpanded(groupPosition);
            if (group instanceof TrashGroupWithIndicator) {
                ((TrashGroupWithIndicator) group).mIsExpand = !expanded;
            }
            if (expanded) {
//                ((ExpandableListView) parent).collapseGroupWithAnimation(groupPosition);
                parent.collapseGroup(groupPosition);
            } else {
                // 不做动画
                parent.expandGroup(groupPosition);
            }
            return true;
        }
        return false;
    }

    /**
     * @return 所有选中的项
     */
    public List<TrashItem> getSelectedTrahItems() {
        ArrayList<TrashItem> items = new ArrayList<TrashItem>();
        for (TrashGroup trashGroup : mTrashGroups) {
            items.addAll(trashGroup.getSelectedTrahItems());
        }
        return items;
    }
}
